package com.testing.sunnycommon.automation;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.util.ArrayList;
import java.util.List;

/**
 * @Classname ExcelUtils
 * @Description 可以完成excel内容的写入，并且其中包含一部分预设样式
 * @Date 2023/6/7 20:46
 * @Created by 特斯汀Roy
 */
@Slf4j
public class ExcelUtils {
    //最终生成的excel文件内容在内存中的存储类型
    private XSSFWorkbook workbook = null;

    public XSSFWorkbook getWorkbook() {
        return workbook;
    }

    //正在进行操作的sheet页
    private Sheet sheet;

    //单元格样式
    private CellStyle defaultStyle = null;
    private CellStyle passStyle = null;
    private CellStyle failStyle = null;
    private CellStyle skippedStyle = null;
    //用例行
    private CellStyle caseStyle = null;
    private CellStyle casePassStyle = null;
    private CellStyle caseFailStyle = null;
    private CellStyle caseSkippedStyle = null;
    //表头行
    private CellStyle headerStyle = null;

    /**
     * 对外提供可以用来设置一个新的样式
     *
     * @param bgColor
     * @param fontColor
     * @param isBold
     * @return
     */
    public CellStyle createResultCellStyle(IndexedColors bgColor, IndexedColors fontColor, boolean isBold) {
        //创建单元格样式对象
        CellStyle resultCellStyle = workbook.createCellStyle();
        //设置背景色
        resultCellStyle.setFillForegroundColor(bgColor.getIndex());
        resultCellStyle.setFillPattern(FillPatternType.THICK_FORWARD_DIAG);
        //设置字体颜色
        Font resultCellFont = workbook.createFont();
        resultCellFont.setColor(fontColor.getIndex());
        //设置是否加粗
        resultCellFont.setBold(isBold);

        resultCellStyle.setFont(resultCellFont);
        //设置边框
        resultCellStyle.setBorderLeft(BorderStyle.THIN);
        resultCellStyle.setBorderRight(BorderStyle.THIN);
        resultCellStyle.setBorderTop(BorderStyle.THIN);
        resultCellStyle.setBorderBottom(BorderStyle.THIN);
        return resultCellStyle;
    }

    /***
     * 初始化结果表格中的样式类型
     */
    private void initCellStyle() {
        //表头
        headerStyle = createResultCellStyle(IndexedColors.WHITE, IndexedColors.BLACK, true);
        //步骤行
        defaultStyle = createResultCellStyle(IndexedColors.WHITE, IndexedColors.BLACK, false);
        passStyle = createResultCellStyle(IndexedColors.WHITE, IndexedColors.BRIGHT_GREEN, true);
        failStyle = createResultCellStyle(IndexedColors.WHITE, IndexedColors.DARK_RED, true);
        skippedStyle = createResultCellStyle(IndexedColors.WHITE, IndexedColors.DARK_YELLOW, true);
        //用例行
        caseStyle = createResultCellStyle(IndexedColors.YELLOW, IndexedColors.BLACK, true);
        casePassStyle = createResultCellStyle(IndexedColors.YELLOW, IndexedColors.BRIGHT_GREEN, true);
        caseFailStyle = createResultCellStyle(IndexedColors.YELLOW, IndexedColors.RED1, true);
        caseSkippedStyle = createResultCellStyle(IndexedColors.YELLOW, IndexedColors.DARK_YELLOW, true);
    }


    /**
     * 使用匿名内部类，来实现ArrayList接口中的内容，从而完成list的初始化添加
     */
    private List<String> header = new ArrayList<>() {{
        add("用例名");
        add("操作步骤");
        add("关键字");
        add("参数1");
        add("参数2");
        add("执行结果");
        add("步骤通过率/执行详情");
    }};

    /**
     * 如果要使用不同的表头信息，通过这个方法传进来。
     *
     * @param header
     */
    public void setHeader(List<String> header) {
        this.header = header;
    }

    /**
     * 构造方法完成workbook实例化和样式的设置
     */
    public ExcelUtils() {
        workbook = new XSSFWorkbook();
        initCellStyle();
    }

    /***
     * 创建sheet页，设置sheet中的列宽和表头列的写入
     * @param sheetName sheet页的名称
     */
    public void createSheet(String sheetName) {
        workbook.createSheet(sheetName);
        this.sheet = workbook.getSheet(sheetName);
        //设置sheet页的大小，以及列宽
        this.sheet.setDefaultColumnWidth(20);
        this.sheet.setColumnWidth(3, 30*256);
        this.sheet.setColumnWidth(4, 30*256);
        this.sheet.setColumnWidth(5, 10*256);
        this.sheet.setColumnWidth(6, 50*256);
        writeLine(0, "header", header);
    }

    /**
     * 写入一行，写入的时候，传一个背景色，来设置整行的写入格式，之后再去调整结果列中的样式
     *
     * @param rowNo
     * @param type       支持三种情况： 表头 、 用例、 步骤
     * @param rowContent
     */
    public void writeLine(int rowNo, String type, List<String> rowContent) {
        Row row = sheet.getRow(rowNo);
        if (row == null) {
            row = sheet.createRow(rowNo);
        }
        //设置一整行的样式
        switch (type) {
            case "header":
                row.setRowStyle(headerStyle);
                break;
            case "case":
                row.setRowStyle(caseStyle);
                break;
            case "step":
            default:
                row.setRowStyle(defaultStyle);
                break;
        }
        //写入单元格内容
        for (int i = 0; i < rowContent.size(); i++) {
            //创建单元格
            Cell cell = row.createCell(i);
            //写入内容
            cell.setCellValue(rowContent.get(i));
            switch (type) {
                case "header":
                    cell.setCellStyle(headerStyle);
                    break;
                case "case":
                    cell.setCellStyle(caseStyle);
                    break;
                case "step":
                default:
                    cell.setCellStyle(defaultStyle);
                    break;
            }

        }
    }


    /**
     * 根据当前行的类型和执行状态，来设置执行结果单元格的样式
     *
     * @param rowNo
     * @param colNo
     * @param type
     * @param status
     */
    public void setStatusCellStyle(int rowNo, int colNo, String type, String status) {
        Cell cell = sheet.getRow(rowNo).getCell(colNo);
        switch (type) {
            case "case":
                switch (status) {
                    case "PASS":
                        // 设置为通过样式
                        cell.setCellStyle(casePassStyle);
                        break;
                    case "FAIL":
                        // 设置失败样式
                        cell.setCellStyle(caseFailStyle);
                        break;
                    case "SKIPPED":
                        cell.setCellStyle(caseSkippedStyle);
                        break;
                }
                break;
            case "step":
                switch (status) {
                    case "PASS":
                        // 设置为通过样式
                        cell.setCellStyle(passStyle);
                        break;
                    case "FAIL":
                        // 设置失败样式
                        cell.setCellStyle(failStyle);
                        break;
                    case "SKIPPED":
                        cell.setCellStyle(skippedStyle);
                        break;
                }
                break;
        }


    }


}
